#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSplitter>
#include <qDebug>
#include <QFileDialog>
#include <QTableWidget>
#include <QDateTime>
#include <QTimer>
#include <QMessageBox>
#include "addbuildingdialog.h"
#include "createprodialog.h"
#include "addfloordialog.h"
#include "addroomdialog.h"
#include "addmaingroupdialog.h"
#include "addmiddlegroupdialog.h"
#include "addgadialog.h"
#include "settabwidgetpage.h"
#include "common.h"
#include "errorcode.h"
#include "managementdatabaseoperations.h"
#include "projectdatabaseoperations.h"
#include "productdatabaseoperations.h"
#include "tabledefine.h"
#include "pmswidget.h"
#include "tppmwidget.h"
#include "relationgadlg.h"
#include "productsummarydlg.h"
#include "serialportsetdlg.h"
#include "configdevicedlg.h"
#include "buildingattributingsetdlg.h"
#include "floorattributingsetdlg.h"
#include "roomattributingsetdlg.h"
#include "deviceattributingsetdlg.h"
#include "maingroupattributingsetdlg.h"
#include "middlegroupattributingsetdlg.h"
#include "gaattributingsetdlg.h"
#include "tpxwidget.h"

extern QString proName;
extern QSqlDatabase ManagementDB;
extern QSqlDatabase projectDB;
extern QSqlDatabase productDB;
extern QStringList oneProjectInfo;

static int serialFlag = 0;

int uniqueDeviceID = -1;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
    //实例化各个对象
    localBuilding = new Building();
    localFloor = new Floor();
    localRoom = new Room();
    localDevice = new Device();
    setTabWidgetFun = new SetTabWidgetPage;
    localMainGroup = new MainGroup;
    localMiddleGroup = new MiddleGroup;
    localGroupAddress = new GroupAddress;
    error = new ErrorToDo;
    
    //初始化主界面
    initMainWindow();
    
    //关联相关的信号和槽函数
    //项目管理
    connect(ui->actionOpenPro, SIGNAL(triggered(bool)), this, SLOT(openProject()));
    connect(ui->actionClosePro, SIGNAL(triggered(bool)), this, SLOT(closeProject()));
    connect(ui->actionCreatePro, SIGNAL(triggered(bool)), this, SLOT(createProject()));
    //设备管理
    connect(ui->actionDM, SIGNAL(triggered(bool)), this, SLOT(DM()));
    //退出
    connect(ui->actionExit, SIGNAL(triggered(bool)), this, SLOT(close()));
    //添加
    connect(ui->actionAddBuilding, SIGNAL(triggered(bool)), this, SLOT(addBuilding()));
    connect(ui->actionAddFloor, SIGNAL(triggered(bool)), this, SLOT(addFloor()));
    connect(ui->actionAddRoom, SIGNAL(triggered(bool)), this, SLOT(addRoom()));
    connect(ui->actionAddDevice, SIGNAL(triggered(bool)), this, SLOT(addDevice()));
    connect(ui->actionAddMainGA, SIGNAL(triggered(bool)), this, SLOT(addMainGroup()));
    connect(ui->actionAddMiddleGA, SIGNAL(triggered(bool)), this, SLOT(addMiddleGroup()));
    connect(ui->actionAddGA, SIGNAL(triggered(bool)), this, SLOT(addGA()));
    //关联及取消关联
    connect(ui->actionRelation, SIGNAL(triggered(bool)), this, SLOT(relationGA()));
    connect(ui->actionCancelLink, SIGNAL(triggered(bool)), this, SLOT(cancelLinkGA()));
    //搜索
    connect(ui->actionSearchDevice, SIGNAL(triggered(bool)), this, SLOT(searchDevice()));
    //下载
    connect(ui->actionDownloadPA, SIGNAL(triggered(bool)), this, SLOT(downloadPA()));
    connect(ui->actionDownloadData, SIGNAL(triggered(bool)), this, SLOT(downloadData()));
    //工具栏
    connect(ui->actionSelectAboutMenu, SIGNAL(triggered(bool)), this, SLOT(selectAboutMenu(bool)));
    connect(ui->actionSelectCloseProMenu, SIGNAL(triggered(bool)), this, SLOT(selectCloseProMenu(bool)));
    connect(ui->actionSelectCreateProMenu, SIGNAL(triggered(bool)), this, SLOT(selectCreateProMenu(bool)));
    connect(ui->actionSelectDBMaintainMenu, SIGNAL(triggered(bool)), this, SLOT(selectDBMaintainMenu(bool)));
    connect(ui->actionSelectExitMenu, SIGNAL(triggered(bool)), this, SLOT(selectExitMenu(bool)));
    connect(ui->actionSelectHelpManualMenu, SIGNAL(triggered(bool)), this, SLOT(selectHelpManualMenu(bool)));
    connect(ui->actionSelectDMMenu, SIGNAL(triggered(bool)), this, SLOT(selectDMMenu(bool)));
    connect(ui->actionSelectOnlineCheckMenu, SIGNAL(triggered(bool)), this, SLOT(selectOnlineCheckMenu(bool)));
    connect(ui->actionSelectOpenProMenu, SIGNAL(triggered(bool)), this, SLOT(selectOpenProMenu(bool)));
    connect(ui->actionSelectPlugInMenu, SIGNAL(triggered(bool)), this, SLOT(selectPlugInMenu(bool)));
    connect(ui->actionSelectactionProductSummaryMenu, SIGNAL(triggered(bool)), this, SLOT(selectactionProductSummaryMenu(bool)));
    connect(ui->actionSelectSerialPortMenu, SIGNAL(triggered(bool)), this, SLOT(selectSerialPortMenu(bool)));
    connect(ui->actionSelectStackMenu, SIGNAL(triggered(bool)), this, SLOT(selectStackMenu(bool)));
    connect(ui->actionSelectTecnicalSupportMenu, SIGNAL(triggered(bool)), this, SLOT(selectTecnicalSupportMenu(bool)));
    connect(ui->actionSelectTileMenu, SIGNAL(triggered(bool)), this, SLOT(selectTileMenu(bool)));
    connect(ui->actionSelectToolBarMenu, SIGNAL(triggered(bool)), ui->mainToolBar, SLOT(setVisible(bool)));
    //产品目录
    connect(ui->actionProductSummary, SIGNAL(triggered(bool)), this, SLOT(productSummary()));
    //诊断
    connect(ui->actionDeviceCheck, SIGNAL(triggered(bool)), this, SLOT(deviceCheck()));
    //工具
    connect(ui->actionPlugIn, SIGNAL(triggered(bool)), this, SLOT(plugIn()));
    connect(ui->actionDBMaintenance, SIGNAL(triggered(bool)), this, SLOT(DBMaintenance()));
    connect(ui->actionOnLineCheck, SIGNAL(triggered(bool)), this, SLOT(OnLineCheck()));
    connect(ui->actionSerialPort, SIGNAL(triggered(bool)), this, SLOT(SerialPort()));
    //窗口
    connect(ui->actionTitle, SIGNAL(triggered(bool)), ui->mdiArea, SLOT(tileSubWindows()));
    connect(ui->actionStack, SIGNAL(triggered(bool)), ui->mdiArea, SLOT(cascadeSubWindows()));
    connect(ui->actionHelpManual, SIGNAL(triggered(bool)), this, SLOT(helpManual()));
    connect(ui->actionTechnicalSupport, SIGNAL(triggered(bool)), this, SLOT(technicalSupport()));
    connect(ui->actionAbout, SIGNAL(triggered(bool)), this, SLOT(about()));
}

MainWindow::~MainWindow()
{
    //关闭对应的数据库
    initManagementDB();
    if(projectDB.isOpen())
        projectDB.close();
    if(ManagementDB.isOpen())    
        ManagementDB.close();
    //删除对应的对象
    delete buildingPage;
    delete floorPage;
    delete roomPage;
    delete devicePage;
    delete parameterPage;
    delete groupObjectPage;
    delete objectRelationPage;
    delete mainGroupPage;
    delete middleGroupPage;
    delete GAPage;
    delete GARelationPage;
    delete error;
    delete ui;
}

void MainWindow::initMainWindow()
{
    setWindowTitle("MyETS");
    ui->mdiArea->tileSubWindows();
    ui->mdiArea->setEnabled(false);
    
    initTreeWidget();
    initStatusBar();
    initTabWidget();
    setAction();
    
    QString dir_str = DB_PATH;
     
    // 检查数据库文件存储目录是否存在，若不存在则新建
    QDir dir;
    if (!dir.exists(dir_str))
    {
        bool res = dir.mkpath(dir_str);
        qDebug() << "新建数据库目录是否成功" << res;
    }
}

void MainWindow::initStatusBar()
{
    currentTimeLabel = new QLabel;
    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(timeUpdate()));  //timeUpdate的声明要在槽函数中
    timer->start(1000); // 每次发射timeout信号时间间隔为1秒
    
    proNameLabel = new QLabel("项目名： ");
    serialPortStatusLabel = new QLabel(" 总线连接状态： 未连接，请设置串口！");
    ui->statusBar->addPermanentWidget(proNameLabel);
    ui->statusBar->addPermanentWidget(serialPortStatusLabel);
    ui->statusBar->addPermanentWidget(currentTimeLabel);
}

void MainWindow::timeUpdate()
{
    QDateTime CurrentTime = QDateTime::currentDateTime();
    QString Timestr = CurrentTime.toString(" yyyy年MM月dd日 hh:mm:ss "); //设置显示的格式
    currentTimeLabel->setText(Timestr);
}

void MainWindow::initTabWidget()
{
    //创建所有的TabWidget中的widget和数据库所需的model和tableView
    createAllCusTomMadeWidget();
    createAllTableView();
    createAllGridLayout();
}

void MainWindow::setTitle()
{
    QString windowTitle("MyETS");
    QString buildingWindowTitle("建筑");
    QString GAWindowTitle("群组地址");
    
    this->setWindowTitle(windowTitle);
    ui->buildingSubwindow->setWindowTitle(buildingWindowTitle);
    ui->GASubwindow->setWindowTitle(GAWindowTitle);
}

void MainWindow::setAction()
{
    buildingTreeWidgetCopyAction = new QAction("复制", this);
    
    buildingAttributeSetAction = new QAction("属性", this);  //建筑属性设置
    connect(buildingAttributeSetAction, SIGNAL(triggered(bool)), this, SLOT(buildingAttributeSet()));
    floorAttributeSetAction = new QAction("属性", this);  //楼层属性设置
    connect(floorAttributeSetAction, SIGNAL(triggered(bool)), this, SLOT(floorAttributeSet()));
    roomAttributeSetAction = new QAction("属性", this);  //房间属性设置
    connect(roomAttributeSetAction, SIGNAL(triggered(bool)), this, SLOT(roomAttributeSet()));
    deviceAttributeSetAction = new QAction("属性", this);  //设备属性设置
    connect(deviceAttributeSetAction, SIGNAL(triggered(bool)), this, SLOT(deviceAttributeSet()));
    buildingTreeWidgetCutAction = new QAction("剪切", this);
    
    buildingTreeWidgetDelAction = new QAction("删除", this);
    connect(buildingTreeWidgetDelAction, SIGNAL(triggered(bool)), this, SLOT(buildingTreeWidgetDelFunc()));
    buildingTreeWidgetPasteAction = new QAction("黏贴", this);
    
    
    GATreeWidgetCopyAction = new QAction("复制", this);
    
    GATreeWidgetCutAction = new QAction("剪贴", this);
    
    GATreeWidgetDelAction = new QAction("删除", this);
    connect(GATreeWidgetDelAction, SIGNAL(triggered(bool)), this, SLOT(GATreeWidgetDelFunc()));
    GATreeWidgetPasteAction = new QAction("黏贴", this);
    
    mainGroupAttributeSetAction = new QAction("属性", this);
    connect(mainGroupAttributeSetAction, SIGNAL(triggered(bool)), this, SLOT(mainGroupAttributeSet()));
    middleGroupAttributeSetAction = new QAction("属性", this);
    connect(middleGroupAttributeSetAction, SIGNAL(triggered(bool)), this, SLOT(middleGroupAttributeSet()));
    GAAttributeSetAction = new QAction("属性", this);
    connect(GAAttributeSetAction, SIGNAL(triggered(bool)), this, SLOT(groupAddressAttributeSet()));
}

void MainWindow::createAllCusTomMadeWidget()
{
    buildingPage = new QWidget();
    floorPage = new QWidget();
    roomPage = new QWidget();
    devicePage = new QWidget();
    parameterPage = new QWidget();
    funcPage = new QWidget();
    groupObjectPage = new QWidget();
    objectRelationPage = new QWidget();
    mainGroupPage = new QWidget();
    middleGroupPage = new QWidget();
    GAPage = new QWidget();
    GARelationPage = new QWidget();
}

void MainWindow::createAllModel()
{
    buildingModel = new QSqlRelationalTableModel(this, projectDB);
    floorModel = new QSqlRelationalTableModel(this, projectDB);
    roomModel= new QSqlRelationalTableModel(this, projectDB);
    deviceModel = new QSqlRelationalTableModel(this, projectDB);
    funcModel = new QSqlRelationalTableModel(this, projectDB);
    groupObjectModel = new QSqlRelationalTableModel(this, projectDB);
    objectRelationModel = new QSqlRelationalTableModel(this, projectDB);
    mainGroupModel = new QSqlRelationalTableModel(this, projectDB);
    middleGroupModel = new QSqlRelationalTableModel(this, projectDB);
    GAModel = new QSqlRelationalTableModel(this, projectDB);
    GARelationModel = new QSqlRelationalTableModel(this, projectDB);
}

void MainWindow::createAllTableView()
{
    buildingView = new QTableView;
    buildingView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    floorView = new QTableView;
    floorView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    roomView = new QTableView;
    roomView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    deviceView = new QTableView;
    deviceView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    funcView = new QTableView;
    funcView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    groupObjectView = new QTableView;
    groupObjectView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //这样设置才可以使用customContextMenuRequested信号，否则无效
    groupObjectView->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(groupObjectView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(updateGroupObjectViewMenu(QPoint)));
    
    objectRelationView = new QTableView;
    objectRelationView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    mainGroupView = new QTableView;
    mainGroupView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    middleGroupView = new QTableView;
    middleGroupView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    GAView = new QTableView;
    GAView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    GARelationView = new QTableView;
    GARelationView->setEditTriggers(QAbstractItemView::NoEditTriggers);
}


void MainWindow::updateGroupObjectViewMenu(const QPoint&)
{
    QMenu *popMenu = new QMenu;
    
    popMenu->addAction(ui->actionRelation);
    popMenu->addAction(ui->actionCancelLink);
    
    //判断是否有关联的组地址，以此判断是否需要取消链接可用
    QString relationID = groupObjectModel->data(groupObjectModel->index(groupObjectView->currentIndex().row(), 15)).toString();
    if(relationID.isNull())
        ui->actionCancelLink->setEnabled(false);
    else
        ui->actionCancelLink->setEnabled(true);
    
    popMenu->exec(QCursor::pos());
}

void MainWindow::createAllGridLayout()
{
    buildingLayout = new QGridLayout;
    floorLayout = new QGridLayout;
    roomLayout = new QGridLayout;
    deviceLayout = new QGridLayout;
    parameterLayout = new QGridLayout;
    funcLayout = new QGridLayout;
    groupObjectLayout = new QGridLayout;
    objectRelationLayout = new QGridLayout;
    mainGroupLayout = new QGridLayout;
    middleGroupLayout = new QGridLayout;
    GALayout = new QGridLayout;
    GARelationLayout = new QGridLayout;
}

void MainWindow::updateModelAndTableView(ModelAndViewType type, QString filter)
{
    switch (type) {
    case BUILDING:
        setTabWidgetFun->setBuildingWidget(buildingModel, buildingView, filter);
        break;
    case FLOOR:
        setTabWidgetFun->setFloorWidget(floorModel, floorView, filter);
        break;
    case ROOM:
        setTabWidgetFun->setRoomWidget(roomModel, roomView, filter);
        break;
    case DEVICE:
        setTabWidgetFun->setDeviceWidget(deviceModel, deviceView, filter);
        break;
    case FUNC:
        setTabWidgetFun->setFuncWidget(funcModel, funcView, filter);
        break;
    case GROUPOBECT:
        setTabWidgetFun->setGroupObjectWidget(groupObjectModel, groupObjectView, filter);
        break;
    case OBJECTRELATION:
        setTabWidgetFun->setObjectRelationWidget(objectRelationModel, objectRelationView, filter);
        break;
    case MAINGROUP:
        setTabWidgetFun->setMainGroupWidget(mainGroupModel, mainGroupView, filter);
        break;
    case MIDDLEGROUP:
        setTabWidgetFun->setMiddleGroupWidget(middleGroupModel, middleGroupView, filter);
        break;
    case GA:
        setTabWidgetFun->setGAWidget(GAModel, GAView, filter);
        break;
    case GARELATION:
        setTabWidgetFun->setGARelationWidget(GARelationModel, GARelationView, filter);
        break;
    default:
        break;
    }
}

void MainWindow::setAllWidgetPage()
{
    setTabWidgetFun->setBuildingWidget(buildingModel, buildingView, "up_id = -1");
    setTabWidgetFun->setPageLayout(buildingLayout, buildingPage, buildingView);
    
    setTabWidgetFun->setFloorWidget(floorModel, floorView, "");
    setTabWidgetFun->setPageLayout(floorLayout, floorPage, floorView);
    
    setTabWidgetFun->setRoomWidget(roomModel, roomView, "");
    setTabWidgetFun->setPageLayout(roomLayout, roomPage, roomView);
    
    setTabWidgetFun->setDeviceWidget(deviceModel, deviceView, "");
    setTabWidgetFun->setPageLayout(deviceLayout, devicePage, deviceView);
    
    setTabWidgetFun->setGroupObjectWidget(groupObjectModel, groupObjectView, "");
    setTabWidgetFun->setPageLayout(groupObjectLayout, groupObjectPage, groupObjectView);
    
    setTabWidgetFun->setObjectRelationWidget(objectRelationModel, objectRelationView, "");
    setTabWidgetFun->setPageLayout(objectRelationLayout, objectRelationPage, objectRelationView);
    
    setTabWidgetFun->setMainGroupWidget(mainGroupModel, mainGroupView, "type != 20");
    setTabWidgetFun->setPageLayout(mainGroupLayout, mainGroupPage, mainGroupView);
    
    setTabWidgetFun->setMiddleGroupWidget(middleGroupModel, middleGroupView, "");
    setTabWidgetFun->setPageLayout(middleGroupLayout, middleGroupPage, middleGroupView);
    
    setTabWidgetFun->setGAWidget(GAModel, GAView, "");
    setTabWidgetFun->setPageLayout(GALayout, GAPage, GAView);
    
    setTabWidgetFun->setGARelationWidget(GARelationModel, GARelationView, "");
    setTabWidgetFun->setPageLayout(GARelationLayout, GARelationPage, GARelationView);
}

void MainWindow::initTreeWidget()
{
    ui->buildingTreeWidget->setHeaderLabel("建筑树状窗口");
    buildingTreeWidgetRoot = new QTreeWidgetItem(ui->buildingTreeWidget, QStringList("建筑"));
    QVariant var0(NODEBUILDINGROOT);
    buildingTreeWidgetRoot->setData(0, Qt::UserRole, var0);
    connect(ui->buildingTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), 
            this, SLOT(updateBuildingTreeWidgetMenu(QPoint)));
    connect(ui->buildingTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), 
            this, SLOT(setTabWidget(QTreeWidgetItem*,int)));
    
    ui->GATreeWidget->setHeaderLabel("群组地址树状窗口");
    GATreeWidgetRoot = new QTreeWidgetItem(ui->GATreeWidget, QStringList("群组地址"));
    QVariant var10(NODEGROUPROOT);
    GATreeWidgetRoot->setData(0, Qt::UserRole, var10);
    connect(ui->GATreeWidget, SIGNAL(customContextMenuRequested(QPoint)), 
            this, SLOT(updateGATreeWidgetMenu(QPoint)));
    connect(ui->GATreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), 
            this, SLOT(setTabWidget(QTreeWidgetItem*,int)));
}

void MainWindow::loadDataFromDBToTreeWidget()
{
    loadToTreeWidgetFromBuildingDB(-1, buildingTreeWidgetRoot);  //从数据库载入已有数据
    ui->buildingTreeWidget->show();
    loadToTreeWidgetFromGADB(-1, GATreeWidgetRoot);
    ui->GATreeWidget->show();
}

void MainWindow::loadToTreeWidgetFromBuildingDB(int id, QTreeWidgetItem *item)
{
    QSqlQuery query(projectDB);
    QString sql = QString("select %1,%2,%3 from %4 where %5 = ?").arg(BUILDING_ID,
                                                                   NAME,
                                                                   TYPE,
                                                                   BUILDING_TABLE_NAME,
                                                                   UP_ID);
    query.prepare(sql);
    query.addBindValue(id);
    if(!query.exec())
    {
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取建筑界面数据库数据失败:"<<query.lastError();
        return;
    }
    while(query.next())
    {
        int curId = query.value(0).toInt();
        QString name = query.value(1).toString();
        int type = query.value(2).toInt();
        QTreeWidgetItem *curItem = new QTreeWidgetItem(item, QStringList(name));
        QVariant var(type);
        curItem->setData(0, Qt::UserRole, var);
        if(!name.isEmpty())
        {
            loadToTreeWidgetFromBuildingDB(curId, curItem);
        }
    }
}

void MainWindow::loadToTreeWidgetFromGADB(int id, QTreeWidgetItem *item)
{
    QSqlQuery query(projectDB);
    QString sql = QString("select %1,%2,%3,%4 from %5 where %6 = ?").arg(ADDRESS_ID,
                                                                   NAME,
                                                                   ADDRESS,
                                                                   TYPE,
                                                                   ADDRESS_TABLE_NAME,
                                                                   UP_ID);
    query.prepare(sql);
    query.addBindValue(id);
    if(!query.exec())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取群组地址界面数据库数据失败:"<<query.lastError();
        error->showCriticalMsg(this, "获取群组地址界面数据库数据失败");
        return;
    }
    while(query.next())
    {
        int curId = query.value(0).toInt();
        QString name = query.value(1).toString();
        QString address = query.value(2).toString();
        int type = query.value(3).toInt();
        QTreeWidgetItem *curItem = new QTreeWidgetItem(item, QStringList(address+name));
        QVariant var(type);
        curItem->setData(0, Qt::UserRole, var);
        if(!name.isEmpty())
        {
            loadToTreeWidgetFromGADB(curId, curItem);
        }
    }
}

void MainWindow::openProject()
{
    PM *pm = new PM();
    pm->show();
    
    if(pm->exec() != QDialog::Accepted)
    {
        return;
    }
    connectManagementDB(MANAGEMENTDB_NAME);
    localProject = new Project();
    
    int projectID = selectProjectIDByFlag(1);
    if(projectID < 0)
    {
        error->showCriticalMsg(this, "打开项目失败，请联系管理员");
        qFatal("从项目管理数据库获取选择的项目id失败");
        exit(GET_PROID_FAILED);
    }
    localProject->setID(projectID);
    if(!selectOneProjectInfo(localProject->getID()))
    {
        error->showCriticalMsg(this, "打开项目失败，请联系管理员");
        qFatal("从项目管理数据库获取当前项目数据失败，将无法打开项目数据库");
        exit(GET_PROINFO_FAILED);
    }
    localProject->setName(oneProjectInfo.at(0));
    localProject->setCreateDateTime(oneProjectInfo.at(1));
    localProject->setLastChangeDateTime(oneProjectInfo.at(2));
    
    QString projectName = localProject->getName();
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"当前项目名："<<projectName;
    proNameLabel->setText(QString("项目名：").append(projectName));
    
    QString localProjectPathName = QString(DB_PATH).append(projectName).append(SUFFIX);
    if(connectProjectDB(localProjectPathName))
    {
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"当前项目数据库连接并打开成功";
        ui->mdiArea->setEnabled(true);
        ui->actionClosePro->setEnabled(true);
        ui->actionCreatePro->setEnabled(false);
        ui->actionOpenPro->setEnabled(false);
        //设置widget、model、tableView
        createAllModel();
        setAllWidgetPage();
        setInitWidget();
        loadDataFromDBToTreeWidget();
    }
}

void MainWindow::closeProject()
{
    updateProjectFlagByID(localProject->getID(), 0);
    delete(localProject);
    ManagementDB.close();
    projectDB.close();
    
    //清空treewidget显示节点
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<buildingTreeWidgetRoot->childCount()<<GATreeWidgetRoot->childCount();
    ui->buildingTreeWidget->clear();
    ui->GATreeWidget->clear();
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除节点成功";
    //然后重新建立root节点
    buildingTreeWidgetRoot = new QTreeWidgetItem(ui->buildingTreeWidget, QStringList("建筑"));
    QVariant var0(NODEBUILDINGROOT);
    buildingTreeWidgetRoot->setData(0, Qt::UserRole, var0);
    GATreeWidgetRoot = new QTreeWidgetItem(ui->GATreeWidget, QStringList("群组地址"));
    QVariant var10(NODEGROUPROOT);
    GATreeWidgetRoot->setData(0, Qt::UserRole, var10);
    
    ui->GATabWidget->clear();
    ui->buildingTabWidget->clear();
    
    ui->mdiArea->setEnabled(false);
    ui->actionClosePro->setEnabled(false);
    ui->actionCreatePro->setEnabled(true);
    ui->actionOpenPro->setEnabled(true);
}

void MainWindow::createProject()
{
    openProject();
}

void MainWindow::DM()
{
    DMDlg *dm = new DMDlg();
    dm->show();
}

void MainWindow::addBuilding()
{
    addBuildingDialog *addBuildDlg = new addBuildingDialog;

    addBuildDlg->show();
    if(addBuildDlg->exec() != QDialog::Accepted)
    {
        return;
    }
    int buildingID = selectNextBuildingID();
    localBuilding->saveAllToDB(buildingID, addBuildDlg->buildingName, "", -1, -1, BUILDING);
    localBuilding->setID(buildingID);
    QString buildingName = localBuilding->getNameFromDBByID();
    if(!buildingName.isEmpty())
    {
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"建筑名称："<<buildingName;
        localBuilding->setAll(buildingID, buildingName, "", -1, -1, BUILDING);
    }
    else
    {
        error->showCriticalMsg(this, "添加节点信息到数据库失败，程序继续执行将无法保证正确性，请联系管理员处理！");
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取建筑名失败";
        return;
    }
    
    //为Treewidget添加节点，通过setData()来为每个节点赋予不同的键值,建筑级节点为1，统一只有一列第0列，使用UserRole
    QTreeWidgetItem *buildingItem = new QTreeWidgetItem(buildingTreeWidgetRoot,QStringList(buildingName));
    QVariant var1(NODEBUILDING);
    buildingItem->setData(0, Qt::UserRole, var1);
    setTabWidget(buildingTreeWidgetRoot, 0);
}

void MainWindow::addFloor()
{
    addFloorDialog *addFloorDlg = new addFloorDialog;

    addFloorDlg->show();
    if(addFloorDlg->exec() != QDialog::Accepted)
    {
        return;
    }
    //楼层节点为建筑节点的子节点，需要先获取建筑节点，根据之前的鼠标右键位置确定
    QTreeWidgetItem *curItem = ui->buildingTreeWidget->currentItem();
    
    int floorID = selectNextBuildingID();
    QString sql = QString("select %1 from %2 where %3 = '%4'").arg(BUILDING_ID, BUILDING_TABLE_NAME, 
                                                                   NAME, curItem->text(0));
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<sql;
    QVariant res = selectBySql(sql);
    if(res.toInt() < 0)
    {
        error->showCriticalMsg(this, "添加节点信息到数据库失败，程序继续执行将无法保证正确性，请联系管理员处理！");
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取楼层上级建筑id失败";
        return;
    }
    localFloor->saveAllToDB(floorID, addFloorDlg->floorName, "", -1, res.toInt(), FLOOR);
    localFloor->setID(floorID);
    QString floorName = localFloor->getNameFromDBByID();
    if(!floorName.isEmpty())
    {
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"楼层名称："<<floorName;
        localFloor->setAll(floorID, floorName, "", -1, res.toInt(), FLOOR);
    }
    else
    {
        error->showCriticalMsg(this, "添加节点信息到数据库失败，程序继续执行将无法保证正确性，请联系管理员处理！");
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取楼层名失败";
        return;
    }
    
    //为Treewidget添加节点，通过setData()来为每个节点赋予不同的键值,楼层级节点键值为1
    QTreeWidgetItem *floorItem = new QTreeWidgetItem(curItem,QStringList(floorName));
    QVariant var2(NODEFLOOR);
    floorItem->setData(0, Qt::UserRole, var2);
    setTabWidget(curItem, 0);
}

void MainWindow::addRoom()
{
    addRoomDialog *addRoomDlg = new addRoomDialog;
    
    addRoomDlg->show();
    if(addRoomDlg->exec() != QDialog::Accepted)
    {
        return;
    }
    //房间节点为建筑或者楼层的子节点，需要通过之前的鼠标点击位置获取父节点
    QTreeWidgetItem *curItem = ui->buildingTreeWidget->currentItem();
    
    int roomID = selectNextBuildingID();
    QString sql = QString("select %1 from %2 where %3 = '%4'").arg(BUILDING_ID, BUILDING_TABLE_NAME, 
                                                                   NAME, curItem->text(0));
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<sql;
    QVariant res = selectBySql(sql);
    if(res.toInt() < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取房间上级id失败";
        error->showCriticalMsg(this, "获取房间上级id失败");
        return;
    }
    localRoom->saveAllToDB(roomID, addRoomDlg->roomName, "", -1, res.toInt(), ROOM);
    localRoom->setID(roomID);
    QString roomName = localRoom->getNameFromDBByID();
    if(!roomName.isEmpty())
    {
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"房间名称："<<roomName;
        localRoom->setAll(roomID, roomName, "", -1, res.toInt(), ROOM);
    }
    else
    {
        error->showCriticalMsg(this, "添加节点信息到数据库失败，程序继续执行将无法保证正确性，请联系管理员处理！");
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取房间名失败";
        return;
    }
    
    //为Treewidget添加节点，通过setData()来为每个节点赋予不同的键值,房间级节点键值为2
    QTreeWidgetItem *roomItem = new QTreeWidgetItem(curItem,QStringList(roomName));
    QVariant var3(NODEROOM);
    roomItem->setData(0, Qt::UserRole, var3);
    setTabWidget(curItem, 0);
}

void MainWindow::addDevice()
{
    DMDlg *dm = new DMDlg();
    dm->show();
    
    if(dm->exec() != QDialog::Accepted)
    {
        return;
    }
    
    QTreeWidgetItem *curItem = ui->buildingTreeWidget->currentItem();
    
    //获取设备表产品信息
    int productID = dm->selectProductID;
    int deviceID = selectNextDeviceID();
    QString productName = dm->selectProductName;
    QString productManufacture = dm->selectProductManufacture;
    QString productOrderNum = dm->selectProductOrderNum;
    QString productAppProgram = dm->selectProductAppProgram;
    QString productVersion = dm->selectProductVersion;
    QString productDBName = dm->selectProductDBName;
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"设备id："<<deviceID;
    
    //在项目数据库设备表判断设备名是否已存在，存在则强制更新，保证设备名唯一
    QString deviceName = productName;
    int ret = isDeviceNameExist(deviceName);
    if(ret == 1)
    {
        deviceName = QString(deviceName).append("%1").arg(deviceID);
        QMessageBox::information(this, "提示信息", QString("由于设备名已存在，设备名将更新为：").append(deviceName));
    }
    if(ret < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"查询设备名是否已存在失败";
        error->showCriticalMsg(this, "查询设备名是否已存在失败");
        return;
    }
    
    //获取建筑id和设备的上级建筑id
    int buildingID = selectNextBuildingID();
    QString sql = QString("select %1 from %2 where %3 = '%4'").arg(BUILDING_ID, BUILDING_TABLE_NAME, 
                                                                   NAME, curItem->text(0));
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<sql;
    QVariant upId = selectBySql(sql);
    if(upId.toInt() < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取设备上级id失败";
        error->showCriticalMsg(this, "数据库操作错误，请删除该设备重新添加");
        return;
    }
    
    //将设备添加到建筑表
    localDevice->setAll(deviceID, productID, buildingID, deviceName, "", productAppProgram, 0, 0, 0, 0, 0,
                        productManufacture, productOrderNum, "", "", "", productVersion, productDBName, "");
    localDevice->addDeviceToBuilding(buildingID, deviceName, "", -1, upId.toInt(), NODEDEVICE);
    
    //存储到项目数据库的设备信息表中
    bool res = localDevice->saveAllToDeviceTable(deviceID, productID, buildingID, deviceName, "", productAppProgram, 0, 0, 0, 0, 0,
                                        productManufacture, productOrderNum, "", "", "", productVersion, productDBName, "", "");
    if(!res)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"插入设备信息到设备信息表失败";
        error->showCriticalMsg(this, "数据库操作错误，请删除该设备重新添加");
        return;
    }
    
    //附加产品数据库到项目数据库
    QSqlQuery query(projectDB);
    QString deviceDBFileName = QString(DB_PATH).append(productDBName).append(SUFFIX);
    if(!query.exec(QString("ATTACH DATABASE  '%1' as productAndProject").arg(deviceDBFileName)))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"attach 失败："<<query.lastError();
        error->showCriticalMsg(this, "数据库操作错误，请删除该设备重新添加");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"attach success";
    
    //将产品数据库的接口对象表信息插入到项目数据库的接口对象表中
    QString tableName = QString("productAndProject.").append(INTERFACE_OBJECT_TABLE_NAME);
    sql.clear();
    sql  = QString("insert into %1 (%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13) select * from %14")
            .arg(INTERFACE_OBJECT_TABLE_NAME).arg(INTERFACE_OBJECT_ID)
            .arg(CHANNEL_NUM).arg(CHANNEL_ID)
            .arg(CHANNEL_NAME).arg(CHANNEL_TYPE)
            .arg(INTERFACE_OBJECT_NUM).arg(EEPROM_ADDRESS)
            .arg(INTERFACE_OBJECT_DESCRIBE).arg(VALUE_SET)
            .arg(VALUE_MEANING).arg(DEFAULT_VALUE)
            .arg(VALUE).arg(tableName);
    if(!query.exec(sql))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"复制接口对象表到项目数据库失败"<<query.lastError();
        error->showCriticalMsg(this, "数据库操作错误，请删除该设备重新添加");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"复制接口对象表到项目数据库成功";
    
    //将产品数据库的通讯对象表信息插入到项目数据库的通讯对象表中
    tableName.clear();
    tableName = QString("productAndProject.").append(COMM_OBJECT_TABLE_NAME);
    sql.clear();
    sql  = QString("insert into %1 (%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14) select * from %15")
            .arg(COMM_OBJECT_TABLE_NAME).arg(COMM_OBJECT_ID)
            .arg(EEPROM_ADDRESS).arg(COMM_OBJECT_NUM)
            .arg(FUNCTION).arg(C_BIT)
            .arg(R_BIT).arg(W_BIT)
            .arg(V_BIT).arg(T_BIT)
            .arg(U_BIT).arg(DATA_TYPE)
            .arg(PRIORITY).arg(RELATION_GA)
            .arg(tableName);
    if(!query.exec(sql))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"复制通讯对象表到项目数据库失败"<<query.lastError();
        error->showCriticalMsg(this, "数据库操作错误，请删除该设备重新添加");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"复制通讯对象表到项目数据库成功";
    
    //规则表暂时不复制，目前暂使用静态方式创建界面，所以规则表暂不使用
    
    //将产品数据库地址表数据插入到项目数据库的地址表中
    tableName.clear();
    tableName = QString("productAndProject.").append(ADDRESS_TABLE_NAME);
    sql.clear();
    sql  = QString("insert into %1 (%2,%3,%4,%5) select * from %6")
            .arg(ADDRESS_TABLE_NAME).arg(ADDRESS_ID)
            .arg(EEPROM_ADDRESS).arg(ADDRESS_NUM)
            .arg(TYPE).arg(tableName);
    if(!query.exec(sql))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"复制地址表到项目数据库失败"<<query.lastError();
        error->showCriticalMsg(this, "数据库操作错误，请删除该设备重新添加");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"复制地址表到项目数据库成功";
    
    //将产品数据库关联表数据插入到项目数据库的关联表中
    tableName.clear();
    tableName = QString("productAndProject.").append(RELATION_TABLE_NAME);
    sql.clear();
    sql  = QString("insert into %1 (%2,%3,%4,%5,%6) select * from %7")
            .arg(RELATION_TABLE_NAME).arg(RELATION_ID)
            .arg(EEPROM_ADDRESS).arg(RELATION_NUM)
            .arg(COMM_OBJECT_NUM).arg(ADDRESS_NUM)
            .arg(tableName);
    if(!query.exec(sql))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"复制关联表到项目数据库失败"<<query.lastError();
        error->showCriticalMsg(this, "数据库操作错误，请删除该设备重新添加");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"复制关联表到项目数据库成功";
    
    //从项目数据库中分离产品数据库
    query.exec("DETACH DATABASE 'productAndProject'");
    productDB.close();
    
    //更新项目数据库中接口对象表、通讯对象表、规则表、地址表、关联表中的设备id和产品id
    if(!updateAllTableProductIDAndDeviceID(productID, deviceID))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新项目数据库的设备id失败";
        error->showCriticalMsg(this, "数据库操作错误，请删除该设备重新添加");
        return;
    }
    
    //为Treewidget添加节点，通过setData()来为每个节点赋予不同的键值,设置级节点键值为3
    QTreeWidgetItem *deviceItem = new QTreeWidgetItem(curItem, QStringList(deviceName));
    QVariant var4(NODEDEVICE);
    deviceItem->setData(0, Qt::UserRole, var4);
    setTabWidget(curItem, 0);
}

void MainWindow::addCommunicationObject(QTreeWidgetItem *deviceItem)
{
    //目前暂时未用到添加通道的地方，暂时都是单通道：2018.12.26
    return;
}

void MainWindow::addMainGroup()
{
    addMainGroupDialog *addMainGroupDlg = new addMainGroupDialog;

    addMainGroupDlg->show();
    if(addMainGroupDlg->exec() != QDialog::Accepted)
    {
        return;
    }
    for(int i = 0;i < (addMainGroupDlg->mainGroupNum);i++)
    {
        int value = i + addMainGroupDlg->mainGroupBeginValue;
        if(isAddressValueExist(value, MAINGROUP) < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"查询地址value是否存在数据库操作失败";
            error->showCriticalMsg(this, "查询地址value是否存在数据库操作失败");
            return;
        }
        while(isAddressValueExist(value, MAINGROUP))  //value存在则继续，直到不存在
        {
            qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"value已存在";
            value++;
            if(value > 15)
            {
                error->showCriticalMsg(this, "主组超过范围,主组范围限定为：0-15");
                qWarning()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"主组超过范围,主组范围限定为：0-15";
                return;
            }
        }
        int addressID = selectNextAddressID();
        QString name = QString("%1").arg(value).append(addMainGroupDlg->mainGroupName);
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"value:"<<value
               <<"addressID:"<<addressID<<"name"<<name;
        
        localMainGroup->setID(addressID);
        if(localMainGroup->saveAllToDB(addressID, value, addMainGroupDlg->mainGroupName, "", -1, 
                                       QString("%1").arg(value), -1, -1, -1, -1,MAINGROUP))
        {
            qInfo()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"添加主群组到数据库成功";
        }
        else
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"插入数据到数据库失败";
            error->showCriticalMsg(this, "插入数据到数据库失败");
            return;
        }
        
        QTreeWidgetItem *mainGroupItem = new QTreeWidgetItem(GATreeWidgetRoot,QStringList(name));
        QVariant var11(NODEMAINGROUP);
        mainGroupItem->setData(0, Qt::UserRole, var11);
        setTabWidget(GATreeWidgetRoot, 0);
    }
}

void MainWindow::addMiddleGroup()
{
    addMiddleGroupDialog *addMiddleGroupDlg = new addMiddleGroupDialog;

    addMiddleGroupDlg->show();
    if(addMiddleGroupDlg->exec() != QDialog::Accepted)
    {
        return;
    }
    QTreeWidgetItem *curItem = ui->GATreeWidget->currentItem();
    for(int i = 0;i < addMiddleGroupDlg->middleGroupNum;i++)
    {
        int value = i + addMiddleGroupDlg->middleGroupBeginValue;
        if(isAddressValueExist(value, MIDDLEGROUP) < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"判断中间组数据在数据库中是否存在失败";
            error->showCriticalMsg(this, "数据库操作失败");
            return;
        }
        while(isAddressValueExist(value, MIDDLEGROUP))  //value存在则继续，直到不存在
        {
            qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"value已存在";
            value++;
            if(value > 7)
            {
                error->showWarningMsg(this, "中间组超过范围，中间组范围限定为：0-7，请按照要求重新添加");
                qWarning()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"中间组超过范围，中间组范围限定为：0-7";
                return;
            }
        }
        
        int addressID = selectNextAddressID();
        QString upAddress = curItem->text(0);
        upAddress = getAddressFromItemName(upAddress, NODEMAINGROUP);
        if(upAddress.isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取中间组的上级主组地址失败";
            error->showCriticalMsg(this, "获取中间组的上级主组失败，请重试");
            return;
        }
        QVariant res = selectBySql(QString("select %1 from %2 where %3 = '%4'").arg(ADDRESS_ID, ADDRESS_TABLE_NAME, ADDRESS, upAddress));
        if(res.toInt() < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"从数据库获取中间组的上级主组地址id失败";
            error->showCriticalMsg(this, "数据库操作错误");
            return;
        }
        
        QString address = upAddress.append(QString("/%1").arg(value));
        QString name = address + addMiddleGroupDlg->middleGroupName;
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<name;
        
        localMiddleGroup->setID(addressID);
        if(localMiddleGroup->saveAllToDB(addressID, value, addMiddleGroupDlg->middleGroupName, "", res.toInt(), 
                                       address, -1, -1, -1, -1, MIDDLEGROUP))
        {
            qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"添加中间组到数据库成功";
        }
        else
        {
            error->showCriticalMsg(this, "插入数据到数据库失败");
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"插入中间组数据到数据库失败";
            return;
        }
        
        QTreeWidgetItem *middleGroupItem = new QTreeWidgetItem(curItem,QStringList(name));
        QVariant var12(NODEMIDDLEGROUP);
        middleGroupItem->setData(0, Qt::UserRole, var12);
        setTabWidget(GATreeWidgetRoot, 0);
    }
}

void MainWindow::addGA()
{
    addGADialog *addGADlg = new addGADialog;

    addGADlg->show();
    if(addGADlg->exec() != QDialog::Accepted)
    {
        return;
    }
    QTreeWidgetItem *curItem = ui->GATreeWidget->currentItem();
    for(int i = 0;i < addGADlg->GANum;i++)
    {
        int value = i + addGADlg->GABeginValue;
        if(isAddressValueExist(value, GA) < 0)
        {
            error->showCriticalMsg(this, "数据库操作失败");
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"判断子组数据是否存在于数据库失败";
            return;
        }
        while(isAddressValueExist(value, GA))  //value存在则继续，直到不存在
        {
            qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"value已存在";
            value++;
            if(value > 255)
            {
                error->showCriticalMsg(this, "子组超过范围，子组范围限定为：0-255，请按照要求重新添加");
                qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"子组超过范围，子组范围限定为：0-255";
                return;
            }
        }
        
        int addressID = selectNextAddressID();
        QString upAddress = curItem->text(0);
        upAddress = getAddressFromItemName(upAddress, NODEMIDDLEGROUP);
        if(upAddress.isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取子组的上级中间组地址失败";
            error->showCriticalMsg(this, "获取子组的上级中间组失败，请重试");
            return;
        }
        QVariant res = selectBySql(QString("select %1 from %2 where %3 = '%4'").arg(ADDRESS_ID, ADDRESS_TABLE_NAME, ADDRESS, upAddress));
        if(res.toInt() < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"从数据库获取子组的上级中间组地址id失败";
            error->showCriticalMsg(this, "数据库操作错误");
            return;
        }
        
        QString address = upAddress.append(QString("/%1").arg(value));
        QString name = address + addGADlg->GAName;
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<name;
        
        localGroupAddress->setID(addressID);
        if(localGroupAddress->saveAllToDB(addressID, value, addGADlg->GAName, "", res.toInt(), 
                                       address, -1, -1, -1, -1, GA))
        {
            qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"添加群组地址到数据库成功";
        }
        else
        {
            error->showCriticalMsg(this, "插入数据到数据库失败");
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"插入子组地址数据到数据库失败";
            return;
        }
        
        QTreeWidgetItem *GAItem = new QTreeWidgetItem(curItem,QStringList(name));
        QVariant var13(NODEGA);
        GAItem->setData(0, Qt::UserRole, var13);
        setTabWidget(GATreeWidgetRoot, 0);
    }
}

void MainWindow::updateBuildingTreeWidgetMenu(const QPoint&)
{
    QTreeWidgetItem *curItem = ui->buildingTreeWidget->currentItem();
    int menuType = curItem->data(0, Qt::UserRole).toInt();
    setTabWidget(curItem, 0);  //右键时调用左键点击事件
    
    QMenu *popMenu = new QMenu(this);
    
    buildingTreeWidgetCutAction->setEnabled(false);  //以下几个功能暂未实现，2018-12-21
    buildingTreeWidgetCopyAction->setEnabled(false);
    buildingTreeWidgetPasteAction->setEnabled(false);
    
    switch (menuType) {
    case NODEBUILDINGROOT:  //建筑root节点右键菜单
        popMenu->addAction(ui->actionAddBuilding);
        break;
    case NODEBUILDING:  //建筑节点右键菜单
        popMenu->addAction(ui->actionAddFloor);
        popMenu->addAction(ui->actionAddRoom);
        popMenu->addAction(buildingTreeWidgetDelAction);
        popMenu->addAction(buildingTreeWidgetCutAction);
        popMenu->addAction(buildingTreeWidgetCopyAction);
        popMenu->addAction(buildingTreeWidgetPasteAction);
        popMenu->addAction(buildingAttributeSetAction);
        break;
    case NODEFLOOR:  //楼层节点右键菜单
        popMenu->addAction(ui->actionAddRoom);
        popMenu->addAction(buildingTreeWidgetDelAction);
        popMenu->addAction(buildingTreeWidgetCutAction);
        popMenu->addAction(buildingTreeWidgetCopyAction);
        popMenu->addAction(buildingTreeWidgetPasteAction);
        popMenu->addAction(floorAttributeSetAction);
        break;
    case NODEROOM:  //房间节点右键菜单
        popMenu->addAction(ui->actionAddDevice);
        popMenu->addAction(buildingTreeWidgetDelAction);
        popMenu->addAction(buildingTreeWidgetCutAction);
        popMenu->addAction(buildingTreeWidgetCopyAction);
        popMenu->addAction(buildingTreeWidgetPasteAction);
        popMenu->addAction(roomAttributeSetAction);
        break;
    case NODEDEVICE:  //设备节点右键菜单
        popMenu->addAction(ui->actionSearchDevice);
        popMenu->addAction(ui->actionDownloadPA);
        popMenu->addAction(ui->actionDownloadData);
        popMenu->addAction(buildingTreeWidgetDelAction);
        popMenu->addAction(buildingTreeWidgetCutAction);
        popMenu->addAction(buildingTreeWidgetCopyAction);
        popMenu->addAction(buildingTreeWidgetPasteAction);
        popMenu->addAction(deviceAttributeSetAction);
        break;
    case NODECHANNEL:  //通道节点右键菜单
        break;
    default:
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"未知节点值";
        error->showCriticalMsg(this, "未知错误");
        return ;
    }
    
    popMenu->exec(QCursor::pos());
    return ;
}

void MainWindow::updateGATreeWidgetMenu(const QPoint&)
{
    QTreeWidgetItem *curItem = ui->GATreeWidget->currentItem();
    int menuType = curItem->data(0, Qt::UserRole).toInt();
    setTabWidget(curItem, 0);  //右键时调用左键点击事件
    
    QMenu *popMenu = new QMenu(this);
    GATreeWidgetCopyAction->setEnabled(false);
    GATreeWidgetPasteAction->setEnabled(false);
    GATreeWidgetCutAction->setEnabled(false);
    
    switch (menuType) {
    case NODEGROUPROOT:  //群组地址root节点右键菜单
        popMenu->addAction(ui->actionAddMainGA);
        break;
    case NODEMAINGROUP:  //主群组节点右键菜单
        popMenu->addAction(ui->actionAddMiddleGA);
        popMenu->addAction(GATreeWidgetDelAction);
        popMenu->addAction(GATreeWidgetCutAction);
        popMenu->addAction(GATreeWidgetCopyAction);
        popMenu->addAction(GATreeWidgetPasteAction);
        popMenu->addAction(mainGroupAttributeSetAction);
        break;
    case NODEMIDDLEGROUP:  //中间群组节点右键菜单
        popMenu->addAction(ui->actionAddGA);
        popMenu->addAction(GATreeWidgetDelAction);
        popMenu->addAction(GATreeWidgetCutAction);
        popMenu->addAction(GATreeWidgetCopyAction);
        popMenu->addAction(GATreeWidgetPasteAction);
        popMenu->addAction(middleGroupAttributeSetAction);
        break;
    case NODEGA:  //群组地址节点右键菜单
        popMenu->addAction(GATreeWidgetDelAction);
        popMenu->addAction(GATreeWidgetCutAction);
        popMenu->addAction(GATreeWidgetCopyAction);
        popMenu->addAction(GATreeWidgetPasteAction);
        popMenu->addAction(GAAttributeSetAction);
        break;
    default:
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"未知节点值";
        error->showCriticalMsg(this, "未知错误");
        return ;
    }
    
    popMenu->exec(QCursor::pos());
    return ;
}

void MainWindow::buildingTreeWidgetDelFunc()
{
    QTreeWidgetItem* item = ui->buildingTreeWidget->currentItem();
    if(item->childCount() > 0)
    {
        for(int i = 0; i < item->childCount(); i ++)
        {
            del(item->child(i));
        }
    }
    deleteDataFromDBByName(item);
    delete item;
}

void MainWindow::GATreeWidgetDelFunc()
{
    QTreeWidgetItem* item = ui->GATreeWidget->currentItem();
    if(item->childCount() > 0)
    {
        for(int i = 0; i < item->childCount(); i ++)
        {
            del(item->child(i));
        }
    }
    deleteDataFromDBByName(item);
    delete item;
}

QString MainWindow::getAddressFromItemName(QString itemName, ItemTypeNum type)
{
    QRegExp MainGroup;
    if(type == NODEMAINGROUP)
        MainGroup = QRegExp("^[0-9]");
    else if(type == NODEMIDDLEGROUP)
        MainGroup = QRegExp("^[0-9]/[0-9]+");
    else if(type == NODEGA)
        MainGroup = QRegExp("^[0-9]/[0-9]+/[0-9]+");
    else
        return NULL;
    
    int pos;
    QString address;
    
    pos = MainGroup.indexIn(itemName);
    if(pos > -1)
    {
        address = MainGroup.cap(0);
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"address:"<<address;
        return address;
    }
    return NULL;
}

void MainWindow::deleteDataFromDBByName(QTreeWidgetItem* item)
{   
    int itemNum = item->data(0, Qt::UserRole).toInt();
    QString address;
    int deviceID;
    
    switch (itemNum) {
    case NODEBUILDING:
    case NODEFLOOR:
    case NODEROOM:
        deleteBuildingByName(item->text(0));
        break;
    case NODEDEVICE:
        deviceID = selectDeviceIDByName(item->text(0));
        if(deviceID < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取要删除的设备的id失败";
            error->showCriticalMsg(this, "从数据库删除设备相关数据失败，请联系管理员");
            return;
        }
        if(!deleteAllDeviceDataByDeviceID(deviceID))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除设备数据库操作失败";
            error->showCriticalMsg(this, "从数据库删除设备相关数据失败，请联系管理员");
        }
        break;
    case NODEMAINGROUP:
        address = getAddressFromItemName(item->text(0), NODEMAINGROUP);
        if(address.isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取要删除的主组值失败";
            error->showCriticalMsg(this, "获取要删除的主组值失败");
            return;
        }
        if(!deleteAddressByAddressAndType(address, NODEMAINGROUP))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除主组值数据库操作失败";
            error->showCriticalMsg(this, "从数据库删除主组相关数据失败，请联系管理员");
        }
        break;
    case NODEMIDDLEGROUP:
        address = getAddressFromItemName(item->text(0), NODEMIDDLEGROUP);
        if(address.isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取要删除的中间组值失败";
            error->showCriticalMsg(this, "获取要删除的中间组值失败");
            return;
        }
        if(!deleteAddressByAddressAndType(address, NODEMIDDLEGROUP))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除中间组值数据库操作失败";
            error->showCriticalMsg(this, "从数据库删除中间组相关数据失败，请联系管理员");
        }
        break;
    case NODEGA:
        address = getAddressFromItemName(item->text(0), NODEGA);
        if(address.isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取要删除的子组值失败";
            error->showCriticalMsg(this, "获取要删除的子组值失败");
            return;
        }
        if(!deleteAddressByAddressAndType(address, NODEGA))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除子组值数据库操作失败";
            error->showCriticalMsg(this, "从数据库删除子组相关数据失败，请联系管理员");
        }
        break;
    default:
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"未知节点值";
        error->showCriticalMsg(this, "未知错误");
        return;
    }
}

void MainWindow::del(QTreeWidgetItem* node)
{
    if(node->childCount() > 0)
    {
        for(int i = 0; i < node->childCount(); i ++)
        {
            deleteDataFromDBByName(node);
            del(node->child(i));
        }
    }
    else
    {
        deleteDataFromDBByName(node);
        delete node;
    }
}

void MainWindow::removeTabWidgetPage(int itemType)
{
    if(itemType < 10)
    {
        ui->buildingTabWidget->clear();  //只是移除，并不会删除
    }
    if(itemType >= 10)
    {
        ui->GATabWidget->clear();
    }
}

void MainWindow::buildingAttributeSet()
{
    buildingAttributingSetDlg *buildingAttributeSetDlg = new buildingAttributingSetDlg;
    buildingAttributeSetDlg->show();
    
    if(buildingAttributeSetDlg->exec() != QDialog::Accepted)
        return;
    
    //获取当前建筑id
    QString nodeName = ui->buildingTreeWidget->currentItem()->text(0);
    if(nodeName.isEmpty())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"未获取到当前建筑节点的名字";
        error->showCriticalMsg(this, "未获取到当前建筑的名称");
        return;
    }
    int buildingID = selectBuildingIDByName(nodeName);
    if(buildingID < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取建筑id失败";
        error->showCriticalMsg(this, "更新建筑属性失败，请联系管理员");
        return;
    }
    
    //更新建筑名、描述或序号，注意序号要转换为int型存储
    if(!buildingAttributeSetDlg->name.isEmpty())
    {
        if(!updateBuildingName(buildingID, buildingAttributeSetDlg->name))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑名失败";
            error->showCriticalMsg(this, "更新建筑名失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑名成功";
    }
    if(!buildingAttributeSetDlg->describe.isEmpty())
    {
        if(!updateBuildingDescribe(buildingID, buildingAttributeSetDlg->describe))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑描述失败";
            error->showCriticalMsg(this, "更新建筑描述失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑描述成功";
    }
    if(!buildingAttributeSetDlg->num.isEmpty())
    {
        if(!updateBuildingNum(buildingID, buildingAttributeSetDlg->num.toInt()))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑序号失败";
            error->showCriticalMsg(this, "更新建筑序号失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑描述成功";
    }
    
    //更新节点名称
    if(!buildingAttributeSetDlg->name.isEmpty())
        ui->buildingTreeWidget->currentItem()->setText(0, buildingAttributeSetDlg->name);
}

void MainWindow::floorAttributeSet()
{
    FloorAttributingSetDlg *floorAttributeSetDlg = new FloorAttributingSetDlg;
    floorAttributeSetDlg->show();
    
    if(floorAttributeSetDlg->exec() != QDialog::Accepted)
        return;
    
    //获取当前建筑id
    QString nodeName = ui->buildingTreeWidget->currentItem()->text(0);
    if(nodeName.isEmpty())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"未获取到当前楼层节点的名字";
        error->showCriticalMsg(this, "未获取到当前楼层的名称");
        return;
    }
    int buildingID = selectBuildingIDByName(nodeName);
    if(buildingID < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取建筑id失败";
        error->showCriticalMsg(this, "更新楼层属性失败，请联系管理员");
        return;
    }
    
    //更新楼层名、描述或序号，注意序号要转换为int型存储
    if(!floorAttributeSetDlg->name.isEmpty())
    {
        if(!updateBuildingName(buildingID, floorAttributeSetDlg->name))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新楼层名失败";
            error->showCriticalMsg(this, "更新楼层名失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新楼层名成功";
    }
    if(!floorAttributeSetDlg->describe.isEmpty())
    {
        if(!updateBuildingDescribe(buildingID, floorAttributeSetDlg->describe))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新楼层描述失败";
            error->showCriticalMsg(this, "更新楼层描述失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新楼层描述成功";
    }
    if(!floorAttributeSetDlg->num.isEmpty())
    {
        if(!updateBuildingNum(buildingID, floorAttributeSetDlg->num.toInt()))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新楼层序号失败";
            error->showCriticalMsg(this, "更新楼层序号失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑描述成功";
    }
    
    //注意更新节点名称
    if(!floorAttributeSetDlg->name.isEmpty())
        ui->buildingTreeWidget->currentItem()->setText(0, floorAttributeSetDlg->name);
}

void MainWindow::roomAttributeSet()
{
    RoomAttributingSetDlg *roomAttributeSetDlg = new RoomAttributingSetDlg;
    roomAttributeSetDlg->show();
    
    if(roomAttributeSetDlg->exec() != QDialog::Accepted)
        return;
    
    //获取当前建筑id
    QString nodeName = ui->buildingTreeWidget->currentItem()->text(0);
    if(nodeName.isEmpty())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"未获取到当前房间节点的名字";
        error->showCriticalMsg(this, "未获取到当前房间的名称");
        return;
    }
    int buildingID = selectBuildingIDByName(nodeName);
    if(buildingID < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取建筑id失败";
        error->showCriticalMsg(this, "更新房间属性失败，请联系管理员");
        return;
    }
    
    //更新房间名、描述或序号，注意序号要转换为int型存储
    if(!roomAttributeSetDlg->name.isEmpty())
    {
        if(!updateBuildingName(buildingID, roomAttributeSetDlg->name))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑名失败";
            error->showCriticalMsg(this, "更新建筑名失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑名成功";
    }
    if(!roomAttributeSetDlg->describe.isEmpty())
    {
        if(!updateBuildingDescribe(buildingID, roomAttributeSetDlg->describe))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑描述失败";
            error->showCriticalMsg(this, "更新建筑描述失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑描述成功";
    }
    if(!roomAttributeSetDlg->num.isEmpty())
    {
        if(!updateBuildingNum(buildingID, roomAttributeSetDlg->num.toInt()))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑序号失败";
            error->showCriticalMsg(this, "更新建筑序号失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑描述成功";
    }
    
    //更新节点名称
    if(!roomAttributeSetDlg->name.isEmpty())
        ui->buildingTreeWidget->currentItem()->setText(0, roomAttributeSetDlg->name);
}

void MainWindow::deviceAttributeSet()
{
    DeviceAttributingSetDlg *deviceAttributeSetDlg = new DeviceAttributingSetDlg;
    deviceAttributeSetDlg->show();
    
    if(deviceAttributeSetDlg->exec() != QDialog::Accepted)
        return;
    
    //获取当前设备id和建筑id
    QString nodeName = ui->buildingTreeWidget->currentItem()->text(0);
    if(nodeName.isNull())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"未获取到当前设备节点的名字";
        error->showCriticalMsg(this, "未获取到当前设备的名称");
        return;
    }
    int deviceID = selectDeviceIDByName(nodeName);
    if(deviceID < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取设备id失败";
        error->showCriticalMsg(this, "更新设备属性失败，请联系管理员");
        return;
    }
    int buildingID = selectBuildingIDByName(nodeName);
    if(buildingID < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取设备建筑表id失败";
        error->showCriticalMsg(this, "更新设备属性失败，请联系管理员");
        return;
    }
    
    //更新设备名称，注意：包括建筑表和设备表两个部分
    if(!deviceAttributeSetDlg->name.isEmpty())
    {
        if(!updateDeviceName(deviceID, deviceAttributeSetDlg->name))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新设备表设备名失败";
            error->showCriticalMsg(this, "更新设备名失败，请联系管理员");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新设备名成功";
        if(!updateBuildingName(buildingID, deviceAttributeSetDlg->name))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新建筑表设备名失败";
            error->showCriticalMsg(this, "更新设备名失败，请联系管理员");
            return;
        }
    }
    
    //更新设备物理地址
    if(!deviceAttributeSetDlg->PA.isNull())
    {
        if(!updateDevicePA(deviceID, deviceAttributeSetDlg->PA))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新设备物理地址失败";
            error->showCriticalMsg(this, "更新设备物理地址失败，请联系管理员");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新设备物理地址成功";
    }
    
    //更新设备描述
    if(!deviceAttributeSetDlg->describe.isNull())
    {
        if(!updateDeviceDescribe(deviceID, deviceAttributeSetDlg->describe))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新设备物理地址失败";
            error->showCriticalMsg(this, "更新设备物理地址失败，请联系管理员");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新设备描述成功";
    }
    
    //更新节点名称
    if(!deviceAttributeSetDlg->name.isEmpty())
        ui->buildingTreeWidget->currentItem()->setText(0, deviceAttributeSetDlg->name);
}

void MainWindow::mainGroupAttributeSet()
{
    MainGroupAttributingSetDlg *mainGroupAttributingSetDlg = new MainGroupAttributingSetDlg;
    mainGroupAttributingSetDlg->show();
    
    if(mainGroupAttributingSetDlg->exec() != QDialog::Accepted)
        return;
    
    //获取地址值，根据value值和type值获取群组地址表唯一行id
    QString address = getAddressFromItemName(ui->GATreeWidget->currentItem()->text(0), NODEMAINGROUP);
    if(address.isEmpty())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"提取地址失败";
        error->showCriticalMsg(this, "修改主群组属性失败");
        return;
    }
    int id = selectIDByAddressAndType(address, NODEMAINGROUP);
    if(id < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取地址表唯一id失败";
        error->showCriticalMsg(this, "修改主群组属性失败");
        return;
    }
    
    //更新主群组名称
    if(!mainGroupAttributingSetDlg->name.isEmpty())
        updateAddressName(id, mainGroupAttributingSetDlg->name);
    
    //更新主群组描述
    if(!mainGroupAttributingSetDlg->describe.isEmpty())
        updateAddressDescribe(id, mainGroupAttributingSetDlg->describe);
    
    //更新节点名称
    if(!mainGroupAttributingSetDlg->name.isEmpty())
        ui->GATreeWidget->currentItem()->setText(0, address.append(mainGroupAttributingSetDlg->name));
}

void MainWindow::middleGroupAttributeSet()
{
    MiddleGroupAttributingSetDlg *middleGroupAttributingSetDlg = new MiddleGroupAttributingSetDlg;
    middleGroupAttributingSetDlg->show();
    
    if(middleGroupAttributingSetDlg->exec() != QDialog::Accepted)
        return;
    
    //获取地址值，根据value值和type值获取群组地址表唯一行id
    QString address = getAddressFromItemName(ui->GATreeWidget->currentItem()->text(0), NODEMIDDLEGROUP);
    if(address.isEmpty())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"提取地址失败";
        error->showCriticalMsg(this, "修改中间组属性失败");
        return;
    }
    int id = selectIDByAddressAndType(address, NODEMAINGROUP);
    if(id < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取地址表唯一id失败";
        error->showCriticalMsg(this, "修改中间组属性失败");
        return;
    }
    
    //更新中间组名称
    if(!middleGroupAttributingSetDlg->name.isEmpty())
        updateAddressName(id, middleGroupAttributingSetDlg->name);
    
    //更新中间组描述
    if(!middleGroupAttributingSetDlg->describe.isEmpty())
        updateAddressDescribe(id, middleGroupAttributingSetDlg->describe);
    
    //更新节点名称
    if(!middleGroupAttributingSetDlg->name.isEmpty())
        ui->GATreeWidget->currentItem()->setText(0, address.append(middleGroupAttributingSetDlg->name));
}

void MainWindow::groupAddressAttributeSet()
{
    GAAttributingSetDlg *gaAttributingSetDlg = new GAAttributingSetDlg;
    gaAttributingSetDlg->show();
    
    if(gaAttributingSetDlg->exec() != QDialog::Accepted)
        return;
    
    //获取地址值，根据value值和type值获取群组地址表唯一行id
    QString address = getAddressFromItemName(ui->GATreeWidget->currentItem()->text(0), NODEGA);
    if(address.isEmpty())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"提取地址失败";
        error->showCriticalMsg(this, "修改群组地址属性失败");
        return;
    }
    int id = selectIDByAddressAndType(address, NODEGA);
    if(id < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取地址表唯一id失败";
        error->showCriticalMsg(this, "修改群组地址属性失败");
        return;
    }
    
    //更新群组地址名称
    if(!gaAttributingSetDlg->name.isEmpty())
        updateAddressName(id, gaAttributingSetDlg->name);
    
    //更新群组地址描述
    if(!gaAttributingSetDlg->describe.isEmpty())
        updateAddressDescribe(id, gaAttributingSetDlg->describe);
    
    //更新节点名称
    if(!gaAttributingSetDlg->name.isEmpty())
        ui->GATreeWidget->currentItem()->setText(0, address.append(gaAttributingSetDlg->name));
}

void MainWindow::setInitWidget()
{
    //初始tabWidget界面设置
    setBuildingRootWidget();
    setGARootWidget();
}

void MainWindow::setBuildingRootWidget()
{
    ui->buildingTabWidget->addTab(devicePage, "设备");
    ui->buildingTabWidget->addTab(parameterPage, "参数");
    ui->buildingTabWidget->addTab(buildingPage, "建筑局部");
}

void MainWindow::setBuildingWidget()
{
    ui->buildingTabWidget->addTab(devicePage, "设备");
    ui->buildingTabWidget->addTab(parameterPage, "参数");
    ui->buildingTabWidget->addTab(funcPage, "功能");
    ui->buildingTabWidget->addTab(floorPage, "建筑局部");
}

void MainWindow::setFloorWidget()
{
    ui->buildingTabWidget->addTab(devicePage, "设备");
    ui->buildingTabWidget->addTab(parameterPage, "参数");
    ui->buildingTabWidget->addTab(funcPage, "功能");
    ui->buildingTabWidget->addTab(roomPage, "建筑局部");
}

void MainWindow::setRoomWidget()
{
    ui->buildingTabWidget->addTab(devicePage, "设备");
    ui->buildingTabWidget->addTab(parameterPage, "参数");
    ui->buildingTabWidget->addTab(funcPage, "功能");
}

void MainWindow::setDeviceWidget(QString deviceType)
{
    //设备级显示组对象、参数窗口
    ui->buildingTabWidget->addTab(groupObjectPage, "组对象");
    
    //产品类型目前根据已有的设备自定义
    QStringList productType;
    productType << "PMS"  << "TPPM"<<"TPX";
    
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"设备类型："<<deviceType;
    if(deviceType == productType.at(0))
    {
        PMSWidget *pmsWidget = new PMSWidget;
        ui->buildingTabWidget->addTab(pmsWidget, "参数");
    }
    if(deviceType == productType.at(1))
    {
        TPPMWidget *tppmWidget = new TPPMWidget;
        ui->buildingTabWidget->addTab(tppmWidget, "参数");
    }
    if(deviceType == productType.at(2))
    {
        TPXWidget *tpxWidget = new TPXWidget;
        ui->buildingTabWidget->addTab(tpxWidget, "参数");
    }
}

void MainWindow::setChannelWidget()
{
    //通讯对象级显示通道关联、参数窗口
    ui->buildingTabWidget->addTab(objectRelationPage, "关联");
    ui->buildingTabWidget->addTab(parameterPage, "参数");
}

void MainWindow::setGARootWidget()
{
    ui->GATabWidget->addTab(mainGroupPage, "主群组");
}

void MainWindow::setMainGroupWidget()
{
    //主群组级显示中间组窗口
    ui->GATabWidget->addTab(middleGroupPage, "中间组");
}

void MainWindow::setMiddleGroupWidget()
{
    //中间组级显示群组地址窗口
    ui->GATabWidget->addTab(GAPage, "群组地址");
}

void MainWindow::setGAWidget()
{
    //群组地址级显示组地址关联窗口
    ui->GATabWidget->addTab(GARelationPage, "关联");
}

void MainWindow::setTabWidget(QTreeWidgetItem *curItem, int column)
{
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"当前所在列："<<column;
    QVariant var = curItem->data(0, Qt::UserRole);  //计算项目编号
    int itemKeyValue = var.toInt();
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<var;
    QVariant res;
    int ret;
    QString filter;
    QString address;
    
    removeTabWidgetPage(itemKeyValue);  //移除之前的窗口

    switch (itemKeyValue) {
    case NODEBUILDINGROOT:  //左键点击建筑root节点
        setBuildingRootWidget();
        updateModelAndTableView(DEVICE, "");
        filter = QString(UP_ID).append("=%1").arg(-1);
        updateModelAndTableView(BUILDING, filter);
        break;
    case NODEBUILDING:  //左键点击建筑节点
        setBuildingWidget();
        updateModelAndTableView(DEVICE, "");
        ret = selectBuildingIDByName(curItem->text(0));
        if(ret > 0)
        {
            filter = QString(UP_ID).append("=%1").arg(ret);
            updateModelAndTableView(FLOOR, filter);
            filter.clear();
            filter = QString(BUILDING_ID).append("=%1").arg(ret);
            updateModelAndTableView(FUNC, filter);
        }
        break;
    case NODEFLOOR:  //~楼层~
        setFloorWidget();
        updateModelAndTableView(DEVICE, "");
        ret = selectBuildingIDByName(curItem->text(0));
        if(ret > 0)
        {
            filter = QString(UP_ID).append("=%1").arg(ret);
            updateModelAndTableView(ROOM, filter);
            filter.clear();
            filter = QString(BUILDING_ID).append("=%1").arg(ret);
            updateModelAndTableView(FUNC, filter);
        }
        break;
    case NODEROOM:  //~房间~
        setRoomWidget();
        updateModelAndTableView(DEVICE, "");
        ret = selectBuildingIDByName(curItem->text(0));
        if(ret > 0)
        {
            filter = QString(BUILDING_ID).append("=%1").arg(ret);
            updateModelAndTableView(FUNC, filter);
        }
        break;
    case NODEDEVICE:  //~设备~
        //取设备id并更新通讯对象表
        ret = selectDeviceIDByName(curItem->text(0));
        if(ret < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取设备id失败";
            error->showCriticalMsg(this, "获取设备id失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"设备id为："<<ret;
        filter = QString(DEVICE_ID).append("=%1").arg(ret);
        uniqueDeviceID = ret;  //赋值全局变量设备id，便于参数界面识别要处理的设备
        
        res.clear();
        //获取设备类型然后设置参数界面
        res = selectBySql(QString("select %1 from %2 where %3 = '%4'").arg(APP_PROGRAM, DEVICE_TABLE_NAME, NAME, curItem->text(0)));
        if(res.toString().isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取设备类型失败";
            error->showCriticalMsg(this, "获取设备类型失败，请联系管理员");
            return;
        }
        setDeviceWidget(res.toString());
        updateModelAndTableView(GROUPOBECT, filter);
        break;
    case NODECHANNEL:  //~通道~
        setChannelWidget();
        break;
    case NODEGROUPROOT:  //~群组地址root~
        setGARootWidget();
        filter = QString("up_id = -1 and type != 20");
        updateModelAndTableView(MAINGROUP, filter);
        break;
    case NODEMAINGROUP:  //~主群组~
        setMainGroupWidget();
        address = getAddressFromItemName(curItem->text(0), NODEMAINGROUP);
        if(address.isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取节点地址信息失败";
            error->showCriticalMsg(this, "获取节点地址信息失败，无法正常显示对应信息，请报告管理人员");
            return;
        }
        res = selectBySql(QString("select %1 from %2 where %3 = '%4'").arg(ADDRESS_ID, 
                                                                        ADDRESS_TABLE_NAME, 
                                                                        ADDRESS, address));
        if(res.toInt() > 0)  //在群组地址表中显示上级id为主群组的群组id
        {
            updateModelAndTableView(MIDDLEGROUP, QString("up_id = %1").arg(res.toInt()));
        }
        break;
    case NODEMIDDLEGROUP:  //~中间组~
        setMiddleGroupWidget();
        address = getAddressFromItemName(curItem->text(0), NODEMIDDLEGROUP);  //获取中间组地址
        if(address.isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取节点地址信息失败";
            error->showCriticalMsg(this, "获取节点地址信息失败，无法正常显示对应信息，请报告管理人员");
            return;
        }
        res = selectBySql(QString("select %1 from %2 where %3 = '%4'").arg(ADDRESS_ID, 
                                                                        ADDRESS_TABLE_NAME, 
                                                                        ADDRESS, address));
        if(res.toInt() > 0)  //在群组地址表中显示上级id为中间组的群组地址
        {
            updateModelAndTableView(GA, QString("up_id = %1").arg(res.toInt()));
        }
        break;
    case NODEGA:  //~群组地址~
        setGAWidget();
        address = getAddressFromItemName(curItem->text(0), NODEGA);
        if(address.isEmpty())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取节点地址信息失败";
            error->showCriticalMsg(this, "获取节点地址信息失败，无法正常显示对应信息，请报告管理人员");
            return;
        }
        res = selectBySql(QString("select %1 from %2 where %3 = '%4'").arg(ADDRESS_ID, 
                                                                        ADDRESS_TABLE_NAME, 
                                                                        ADDRESS, address));
        if(res.toInt() > 0)  //显示上级id为中间组的群组地址
        {
            updateModelAndTableView(GARELATION, "");
        }
        break;
    default:
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"未识别";
        break;
    }

    return ;
}

void MainWindow::relationGA()
{
    RelationGADlg *relationGADlg = new RelationGADlg;
    
    relationGADlg->show();
    if(relationGADlg->exec() != QDialog::Accepted)
        return;
    
    //获取设备id、产品id
    int productID = groupObjectModel->data(groupObjectModel->index(groupObjectView->currentIndex().row(), 2)).toInt();
    int deviceID = groupObjectModel->data(groupObjectModel->index(groupObjectView->currentIndex().row(), 3)).toInt();
    int commObjectNum = groupObjectModel->data(groupObjectModel->index(groupObjectView->currentIndex().row(), 5)).toInt();
    
    //地址表处理
    //根据获取到的组地址重新插入群组地址表，上级id为-2，类型设为20，获取eeprom地址、设备地址序号信息等然后存入
    QString GA = relationGADlg->GA;
    if(GA.isEmpty())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取关联的组地址失败";
        error->showCriticalMsg(this, "获取关联的组地址失败");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<GA;
    int addressID = selectNextDeviceAddressIDByDeviceID(deviceID);
    if(addressID < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取组地址id失败";
        error->showCriticalMsg(this, "获取组地址id失败");
        return;
    }
    int groupEepromAddress = selectNextGroupEepromAddressByDeviceID(deviceID);
    if(groupEepromAddress < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取eeprom地址失败";
        error->showCriticalMsg(this, "获取eeprom地址失败");
        return;
    }
    int addressNum = selectNextAddressNumByDeviceID(deviceID);
    if(addressNum < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取组地址序列号失败";
        error->showCriticalMsg(this, "获取组地址序列号失败");
        return;
    }
    QString addressName = selectAddressNameByDeviceIDAndGA(-1, GA);
    if(addressName.isEmpty())
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取组地址名称失败";
        error->showCriticalMsg(this, "获取组地址名称失败");
        return;
    }
    if(!insertAddress(addressID, -1, "", "", -2, GA, productID, deviceID, groupEepromAddress, addressNum, NODEDEVICESENDGA))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"插入关联的组地址失败";
        error->showCriticalMsg(this, "插入关联的组地址失败");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"地址表关联处理完成";
    
    //通讯对象表处理
    //插入关联的组地址，并获取其通讯对象序号
    QString relationGA = groupObjectModel->data(groupObjectModel->index(groupObjectView->currentIndex().row(), 15)).toString();
    if(relationGA.isEmpty())
    {
        relationGA = relationGADlg->GA;
        //将组地址名称插入到通讯对象表行描述中，关联的第一个组地址的名称
        if(!updateRelationDescribeByDeviceIDAndObjectNum(deviceID, commObjectNum, addressName))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新关联描述失败";
            error->showCriticalMsg(this, "更新关联描述失败");
            return;
        }
    }
    else
        relationGA = relationGA.append(",").append(relationGADlg->GA);
    
    if(!updateRelationGAByDeviceIDAndCommObjectNum(deviceID, commObjectNum, relationGA))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新关联组地址失败";
        error->showCriticalMsg(this, "更新关联组地址失败");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"通讯对象表关联处理完成";
    
    //关联表处理
    //获取关联序号、组地址序号、关联序号、插入关联信息
    int relationID = selectNextRelationIDByDeviceID(deviceID);
    if(relationID < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取关联id失败";
        error->showCriticalMsg(this, "获取关联id失败");
        return;
    }
    int relationNum = selectNextRelationNumByDeviceID(deviceID);
    if(relationNum < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取关联序号失败";
        error->showCriticalMsg(this, "获取关联序号失败");
        return;
    }
    int relationEepromAddress = selectNextEepromAddressByDeviceID(deviceID);
    if(relationEepromAddress < 0)
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取关联表eeprom地址失败";
        error->showCriticalMsg(this, "获取关联表eeprom地址失败");
        return;
    }
    if(!insertRelation(relationID, productID, deviceID, relationEepromAddress, relationNum, commObjectNum, addressNum))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"插入关联信息到关联表失败";
        error->showCriticalMsg(this, "插入关联信息到关联表失败");
        return;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"关联表关联处理完成";
    updateModelAndTableView(GROUPOBECT, QString(DEVICE_ID).append("=%1").arg(deviceID));
}

void MainWindow::cancelLinkGA()
{
    //获取设备id、产品id、组地址
    int deviceID = groupObjectModel->data(groupObjectModel->index(groupObjectView->currentIndex().row(), 3)).toInt();
    QString relationGA = groupObjectModel->data(groupObjectModel->index(groupObjectView->currentIndex().row(), 15)).toString();
    int commObjectNum = groupObjectModel->data(groupObjectModel->index(groupObjectView->currentIndex().row(), 5)).toInt();
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"设备id："<<deviceID<<"通讯对象序号："<<commObjectNum<<"组地址："<<relationGA;
    
    QStringList GA = relationGA.split(",");
    int flag = 0;
    foreach (QString tmp, GA) {
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<tmp;
        //地址表处理
        //获取其组地址id
        int addressID = selectAddressIDByAddressAndTypeAndDeviceID(tmp, 20, deviceID);
        if(addressID < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取地址id失败";
            error->showCriticalMsg(this, "获取地址id失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"地址id："<<addressID;
        //获取组地址序号
        int addressNum = selectAddressNumByAddressAndDeviceID(tmp, deviceID);
        if(addressNum < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取组地址序号失败";
            error->showCriticalMsg(this, "获取组地址序号失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"地址序号："<<addressNum;
        //根据设备id和组地址，删除关联的设备组地址行，type=20
        if(!deleteAddressByDeviceIDAndGAAndType(deviceID, tmp, 20))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除组地址表关联组地址失败";
            error->showCriticalMsg(this, "删除组地址表关联组地址失败");
            return;
        }
        //更新后续的组地址id、组地址序号、eeprom地址，使其排序，长度
        if(addressID > 1)
        {
            if(!updateAddressIDAndAddressNumAndEepromAddressToOrder(deviceID, addressID))
            {
                qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新后续组地址id、组地址序号、eeprom地址失败";
                error->showCriticalMsg(this, "更新后续组地址id、组地址序号、eeprom地址失败");
                return;
            }
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"取消关联组地址处理完成";
        
        //通讯对象表处理
        //根据通讯对象序号和设备id更新关联的组地址字段
        if(!updateRelationGAAndDescribeNullByCommObjectNumAndDeviceID(deviceID, commObjectNum))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新通讯对象表关联组地址及描述为空失败";
            error->showCriticalMsg(this, "更新通讯对象表关联组地址及描述为空失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"取消关联通讯对象表处理完成";
        
        //关联表处理
        //获取关联id，注意:前一次循环将组地址序号进行了减一，所以得到的组地址序号要比关联表中的组地址序号小一，所以当第二次删关联信息时记得组地址序号加一
        int relationID;
        if(flag)
            relationID = selectRelationIDByDeviceIDAndCommObjectNumAndAddressNum(deviceID, commObjectNum, addressNum + 1);
        if(!flag)
            relationID = selectRelationIDByDeviceIDAndCommObjectNumAndAddressNum(deviceID, commObjectNum, addressNum);
        if(relationID < 0)
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"获取关联id失败";
            error->showCriticalMsg(this, "获取关联id失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"关联id:"<<relationID;
        //删除关联组地址id数据
        if(!deleteRelationByDeviceIDAndCommObjectNumAndAddressNum(deviceID, relationID))
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除关联失败";
            error->showCriticalMsg(this, "删除关联失败");
            return;
        }
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"取消关联关联表处理完成";
        //更新后续的关联id
        if(relationID > 0)
        {
            if(!updateRelationIDAndEepromAddressByDeviceIDAndRelationID(deviceID, relationID))
            {
                qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新后续的关联id失败";
                error->showCriticalMsg(this, "更新后续的关联id失败");
                return;
            }
        }
        
        //循环一次后flag置为1
        flag = 1;
    }
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"取消组地址关联成功";
    updateModelAndTableView(GROUPOBECT, QString(DEVICE_ID).append("=%1").arg(deviceID));
}

void MainWindow::searchDevice()
{
    if(serialFlag != 1)
    {
        qWarning()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"knx串口未连接，请先连接knx串口";
        error->showWarningMsg(this, "knx串口未连接，请先连接knx串口");
        return;
    }
    ConfigDeviceDlg *configDeviceDlg = new ConfigDeviceDlg;
    
    configDeviceDlg->show();
}

void MainWindow::downloadPA()
{
    if(serialFlag != 1)
    {
        qWarning()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"knx串口未连接，请先连接knx串口";
        error->showWarningMsg(this, "knx串口未连接，请先连接knx串口");
        return;
    }
    ConfigDeviceDlg *configDeviceDlg = new ConfigDeviceDlg;
    
    configDeviceDlg->show();
}

void MainWindow::downloadData()
{
    if(serialFlag != 1)
    {
        qWarning()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"knx串口未连接，请先连接knx串口";
        error->showWarningMsg(this, "knx串口未连接，请先连接knx串口");
        return;
    }
    ConfigDeviceDlg *configDeviceDlg = new ConfigDeviceDlg;
    
    configDeviceDlg->show();
}

void MainWindow::selectAboutMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionAbout);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionAbout);
    }
}

void MainWindow::selectCloseProMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionClosePro);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionClosePro);
    }
}

void MainWindow::selectCreateProMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionCreatePro);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionCreatePro);
    }
}

void MainWindow::selectDBMaintainMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionDBMaintenance);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionDBMaintenance);
    }
}

void MainWindow::selectExitMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionExit);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionExit);
    }
}

void MainWindow::selectHelpManualMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionHelpManual);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionHelpManual);
    }
}

void MainWindow::selectDMMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionDM);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionDM);
    }
}

void MainWindow::selectOnlineCheckMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionOnLineCheck);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionOnLineCheck);
    }
}

void MainWindow::selectOpenProMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionOpenPro);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionOpenPro);
    }
}

void MainWindow::selectPlugInMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionPlugIn);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionPlugIn);
    }
}

void MainWindow::selectactionProductSummaryMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionProductSummary);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionProductSummary);
    }
}

void MainWindow::selectSerialPortMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionSerialPort);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionSerialPort);
    }
}

void MainWindow::selectStackMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionStack);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionStack);
    }
}

void MainWindow::selectTecnicalSupportMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionTechnicalSupport);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionTechnicalSupport);
    }
}

void MainWindow::selectTileMenu(bool checked)
{
    if(checked)
    {
        ui->mainToolBar->insertAction(ui->actionPlaceholder, ui->actionTitle);
    }
    else
    {
        ui->mainToolBar->removeAction(ui->actionTitle);
    }
}

void MainWindow::productSummary()
{
    ProductSummaryDlg *productSummargDlg = new ProductSummaryDlg;
    productSummargDlg->show();
}

void MainWindow::deviceCheck()
{
    
}

void MainWindow::plugIn()
{
    
}

void MainWindow::DBMaintenance()
{

}

void MainWindow::OnLineCheck()
{
    
}

void MainWindow::updateSerialStatus(int res)
{
    QString status;
    if(0 == res)
    {
        serialFlag = res;
        status.clear();
        status = " 总线连接状态：已断开 ";
    }
    if(1 == res)
    {
        serialFlag = res;
        status.clear();
        status = " 总线连接状态：已连接 ";
    }
    if(2 == res)
    {
        serialFlag = res;
        status.clear();
        status = " 总线连接状态：连接为非knx串口 ";
    }
    serialPortStatusLabel->setText(status);
}

void MainWindow::SerialPort()
{
    SerialPortSetDlg *serialPortDlg = new SerialPortSetDlg;
    serialPortDlg->show();
    
    connect(serialPortDlg, SIGNAL(finished(int)), this, SLOT(updateSerialStatus(int)));
}

void MainWindow::showBuildingSubWindow()
{
    
}

void MainWindow::showGASubWindow()
{
    
}

void MainWindow::helpManual()
{
    
}

void MainWindow::technicalSupport()
{
    QMessageBox::information(this, "技术支持", 
                       "本软件提供帮助文档，遇到问题请先查看帮助文档。\n"
                       "如果仍无法解决可联系技术和开发人员，遇到软件bug请联系开发人员，我们将及时解决！");
}

void MainWindow::about()
{
    QMessageBox::about(this, "关于", 
                       "本软件由琰尚智能科技有限公司开发，用于配置基于KNX协议的自研发设备！\n"
                       "版权归琰尚智能科技有限公司所有！");
}
